#include "zhiXing.h"
#include "c3_main.h"
#include "mqtt_khd.h"

static const char *TAG = "zhiXing: ";

#include <string.h>
static char json_data[64];
static const char *sheBei = SHE_BEI_MA;

// GPIO初始化
void gpioInit(void)
{
    // 1. 配置GPIO参数
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << KAI_GUAN_01 | 1ULL << KAI_GUAN_02), // 选中要配置的引脚
        .mode = GPIO_MODE_OUTPUT,                                    // 输出模式
        .pull_up_en = GPIO_PULLUP_DISABLE,                           // 禁用上拉
        .pull_down_en = GPIO_PULLDOWN_DISABLE,                       // 禁用下拉
        .intr_type = GPIO_INTR_DISABLE                               // 禁用中断
    };

    // 2. 应用GPIO配置
    esp_err_t err = gpio_config(&io_conf);
    if (err != ESP_OK)
    {
        printf("GPIO配置失败: %s\n", esp_err_to_name(err));
        return;
    }
    gpio_set_level(KAI_GUAN_01, 0);
    gpio_set_level(KAI_GUAN_02, 0);
}

// 定时器回调函数（定时时间到后执行）
static void vTimerCallback(TimerHandle_t xTimer)
{
    // 这里可以用作发送心跳包,或者上报数据

    // 正确的 JSON 字符串（键名用双引号，值为数字）
    // const char *data = "{\"a\":1,\"b\":\"sb\"}";
    mqqt_publish(json_data);

    // 注意：回调函数中应避免阻塞操作（如vTaskDelay），如需阻塞可创建任务处理
}

void ding_shi_qi(void)
{
    // 使用 snprintf 动态拼接 JSON，将 sheBei 插入到 "%s" 对应的位置
    snprintf(json_data, sizeof(json_data), "{\"QQLX\":1,\"sheBei\":\"%s\"}", sheBei);
    // 1. 创建定时器（参数：定时器名称、定时周期、是否周期性触发、参数、回调函数）
    TimerHandle_t xTimer = xTimerCreate(
        "MQTT",                   // 定时器名称（仅用于调试）
        pdMS_TO_TICKS(1000 * 20), // 定时周期（1000ms = 1秒，转换为时钟节拍）
        pdTRUE,                   // pdTRUE=周期性触发，pdFALSE=仅触发一次
        (void *)0,                // 传递给回调函数的参数（无参数时设为0）
        vTimerCallback            // 定时回调函数
    );

    if (xTimer == NULL)
    {
        ESP_LOGE(TAG, "定时器创建失败");
        return;
    }

    // 2. 启动定时器（参数：定时器句柄、阻塞时间（0=立即启动））
    if (xTimerStart(xTimer, 0) != pdPASS)
    {
        ESP_LOGE(TAG, "定时器启动失败");
        return;
    }

    ESP_LOGI(TAG, "FreeRTOS 定时器已启动，周期1秒");
}

void xiao_xi_fen_fa(void *arg)
{
    uint8_t ucRxData[KONGZHIP_XIAO_XI];
    size_t xReceivedBytes = 0;
    //{\"id\":\"c3001\",\"lx\":2,}
    while (true)
    {
        xReceivedBytes = xMessageBufferReceive(zhuanFanP, (void *)ucRxData, sizeof(ucRxData), pdMS_TO_TICKS(20));
        if (xReceivedBytes > 0)
        {
            json_chu_li((char *)ucRxData);
            memset(ucRxData, 0, KONGZHIP_XIAO_XI);
        }
        vTaskDelay(300 / portTICK_PERIOD_MS);
    }
}

bool json_chu_li(const char *data)
{
    ESP_LOGI(TAG, "解析JSON: %s", data);

    // 1. 解析JSON，直接判断是否为空（避免后续重复检查）
    cJSON *root = cJSON_Parse(data);
    if (root == NULL)
    {
        ESP_LOGE(TAG, "JSON解析失败");
        return false; // 解析失败直接返回，无需删除root（已为NULL）
    }

    // 定义清理标签，统一释放资源
    bool result = false;
    cJSON *xiaFaItem = NULL;
    cJSON *beiKongSheBeiItem = NULL;
    cJSON *zhiLingItem = NULL;

    do
    { // 使用do-while循环配合break，简化多层嵌套
        // 2. 获取"xiaFa"字段
        xiaFaItem = cJSON_GetObjectItemCaseSensitive(root, "xiaFa");
        if (xiaFaItem == NULL || !cJSON_IsNumber(xiaFaItem))
        { // 增加类型检查（确保是数字）
            ESP_LOGE(TAG, "缺少或无效的'xiaFa'字段");
            break;
        }
        uint16_t xiaFa = (uint16_t)xiaFaItem->valueint;

        // 3. 处理xiaFa=1（当前无逻辑，保留框架）
        if (xiaFa == 1)
        {
            ESP_LOGI(TAG, "xiaFa=1，无需处理");
            result = true; // 根据实际需求调整是否返回true
            break;
        }

        // 4. 处理xiaFa=2
        if (xiaFa == 2)
        {
            // 4.1 获取"beiKongSheBei"字段（设备码）
            beiKongSheBeiItem = cJSON_GetObjectItemCaseSensitive(root, "beiKongSheBei");
            if (beiKongSheBeiItem == NULL || !cJSON_IsString(beiKongSheBeiItem))
            { // 检查是否为字符串
                ESP_LOGE(TAG, "缺少或无效的'beiKongSheBei'字段");
                break;
            }
            const char *sheBeiMa = beiKongSheBeiItem->valuestring;
            if (sheBeiMa == NULL)
            { // 避免空指针传入strcmp
                ESP_LOGE(TAG, "'beiKongSheBei'字段值为空");
                break;
            }

            // 4.2 对比设备码
            if (strcmp(sheBeiMa, SHE_BEI_MA) != 0)
            {
                ESP_LOGW(TAG, "设备码不匹配（收到: %s, 本地: %s）", sheBeiMa, SHE_BEI_MA);
                break;
            }

            // 4.3 获取"zhiLing"字段（指令）
            zhiLingItem = cJSON_GetObjectItemCaseSensitive(root, "zhiLing");
            if (zhiLingItem == NULL || !cJSON_IsNumber(zhiLingItem))
            { // 检查是否为数字
                ESP_LOGE(TAG, "缺少或无效的'zhiLing'字段");
                break;
            }
            uint16_t zhiLing = (uint16_t)zhiLingItem->valueint;

            // 4.4 执行GPIO控制
            gpio_set_level(KAI_GUAN_01, zhiLing);
            ESP_LOGI(TAG, "执行指令: zhiLing=%d, 已控制GPIO", zhiLing);
            result = true;
            break;
        }

        // 5. 处理未知的xiaFa值
        ESP_LOGE(TAG, "未知的xiaFa值: %d", xiaFa);
    } while (0);

    // 统一释放所有cJSON资源（无论成功失败都执行）
    cJSON_Delete(root);
    return result;
}
